package com.cykj.admin.service.impl;

import com.cykj.admin.mapper.MenuMapper;
import com.cykj.admin.service.IMenuService;
import com.cykj.admin.util.TreeMenuUtils;
import com.cykj.admin.vo.MenuVO;
import com.cykj.common.dto.ResponseDTO;
import com.cykj.common.entity.AdminDO;
import com.cykj.common.entity.MenuDO;
import com.cykj.common.entity.RoleDO;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.util.*;
import java.util.List;

/**
 * @BelongsProject: smart_recruit_backend
 * @BelongsPackage: com.cykj.admin.service.impl
 * @Author: 小小卢
 * @CreateTime: 2025-08-20 09:43
 * @Description: TODO
 * @Version: 1.0
 */
@Service
public class MenuServiceImpl implements IMenuService {

    @Autowired
    private MenuMapper menuMapper;

    /**
     * @Description: 构建树形菜单
     * @Param: [menuVO]
     * @return: com.cykj.common.dto.ResponseDTO
     */
    @Override
    public ResponseDTO buildTreeMenu(MenuVO menuVO) {
        List<MenuDO> list = menuMapper.selectMenuByAdmin(menuVO);
        List<MenuDO> menus = TreeMenuUtils.buildTreeMenu(list);
        return ResponseDTO.success(menus);
    }

    @Override
    public ResponseDTO getAllMenu() {
        List<MenuDO> list = menuMapper.getAllMenu();
        return ResponseDTO.success(list);
    }

    /**
     * @Description: 查询菜单
     * @Param: [menuVO]
     * @return: com.cykj.common.dto.ResponseDTO
     */
    @Override
    public ResponseDTO getMenuByAdmin(MenuVO menuVO) {
        PageInfo<MenuDO> page;
        List<MenuDO> menuList;
        //开启分页
        PageHelper.startPage(menuVO.getCurrentPage(), menuVO.getPageSize());
        menuList = menuMapper.selectMenuByAdmin(menuVO);

        page = new PageInfo<>(menuList);

        if (page.getTotal() != 0 && menuList.isEmpty()) {
            menuVO.setCurrentPage(1);
            PageHelper.startPage(menuVO.getCurrentPage(), menuVO.getPageSize());
            menuList = menuMapper.selectMenuByAdmin(menuVO);
            page = new PageInfo<>(menuList);
        }
        return ResponseDTO.success(page);
    }

    /**
     * @Description: 查询菜单Id
     * @Param: [menuVO]
     * @return: com.cykj.common.dto.ResponseDTO
     */
    @Override
    public ResponseDTO getMenuId() {
        List<MenuDO> list = menuMapper.getAllMenu();
        return ResponseDTO.success(list);
    }

    /**
     * @Description: 新增菜单
     * @Param: [menuVO]
     * @return: com.cykj.common.dto.ResponseDTO
     */
    @Override
    public ResponseDTO addMenu(MenuVO menuVO) {
        Integer row = menuMapper.addMenu(menuVO);
        if (row > 0) {
            return ResponseDTO.success(row);
        }
        return ResponseDTO.error("新增失败");
    }

    /**
     * @Description: 修改菜单
     * @Param: [menuVO]
     * @return: com.cykj.common.dto.ResponseDTO
     */
    @Override
    public ResponseDTO updateMenu(MenuVO menuVO) {
        Integer row = menuMapper.updateMenu(menuVO);
        if (row > 0) {
            return ResponseDTO.success(row);
        }
        return ResponseDTO.error("修改失败");
    }

    @Override
    public ResponseDTO getMenuById(Integer roleId) {
        List<MenuDO> roleMenu = menuMapper.getMenuById(roleId);
        List<MenuDO> allMenu = menuMapper.getAllMenu();
        Set<Integer> menuIds = new HashSet<>();
        HashMap<Integer, MenuDO> menuMap = new HashMap<>();
        //将菜单的id放入set集合中
        for (MenuDO item : roleMenu) {
            menuIds.add(item.getMenuId());
        }
        List<MenuDO> noPer = new ArrayList<>();
        //将不存在menuIds集合中的菜单添加到noPer中
        for (MenuDO item : allMenu) {
            menuMap.put(item.getMenuId(), item);
            if (!menuIds.contains(item.getMenuId())) {
                noPer.add(item);
            }
        }

        //获取noPer中所有菜单的父级菜单ID
        HashSet<Integer> noPerMenuIds = new HashSet<>();
        for (MenuDO item : noPer) {
            noPerMenuIds.add(item.getMenuId());
        }
        //遍历未拥有权限的菜单ID，查看父级菜单是否存在于未拥有权限的菜单集合里，未存在则添加
        List<MenuDO> fullNoPerMenu = new ArrayList<>();
        for (MenuDO item : noPer) {
            fullNoPerMenu.add(item);
            if ((!noPerMenuIds.contains(item.getParentId())) && item.getParentId() != 0) {
                fullNoPerMenu.add(menuMap.get(item.getParentId()));
            }
        }
        HashMap<String, List> MenuHashMap = new HashMap<>();
        roleMenu = TreeMenuUtils.buildTreeMenu(roleMenu);
        fullNoPerMenu = TreeMenuUtils.buildTreeMenu(fullNoPerMenu);
        MenuHashMap.put("roleMenu", roleMenu);
        MenuHashMap.put("fullNoPerMenu", fullNoPerMenu);

        return ResponseDTO.success(MenuHashMap);
    }

    @Override
    public ResponseDTO getAllRole() {
        List<RoleDO> allRole = menuMapper.getAllRole();
        return ResponseDTO.success(allRole);
    }

    @Override
    public ResponseDTO changePerMenu(HashMap<String,Object> roleAndMenu) {
        ObjectMapper objectMapper = new ObjectMapper();

        List<MenuDO> menuList = objectMapper.convertValue(roleAndMenu.get("menuList"), new TypeReference<>() {});
        Integer roleId = (Integer) roleAndMenu.get("roleId");
        menuList = getFullMenu(menuList);
        Integer deleteRows = menuMapper.deletePerMenu(roleId);
        if (deleteRows == 0){
            return ResponseDTO.error("权限菜单修改失败！");
        }
        Integer i = menuMapper.changePerMenu(roleId, menuList);
        if(i>0){
            return ResponseDTO.success("权限菜单修改成功！");
        }
        return ResponseDTO.error("权限菜单修改失败！");
    }

    /**
    * @Description: 获取所有菜单以及子菜单
    * @Param: [menuList]
    * @return: java.util.List<com.cykj.common.entity.MenuDO>
    */
    private List<MenuDO> getFullMenu(List<MenuDO> menuList){
        List<MenuDO> fullMenu = new ArrayList<>();
        for (MenuDO item : menuList) {
            fullMenu.add(item);
            if (!item.getChildren().isEmpty()){
                fullMenu.addAll(getFullMenu(item.getChildren()));
            }
        }
        return fullMenu;
    }

}